#pragma once
#include <iostream>
#include <memory>
#include <string>
#include <jsoncpp/json/json.h>

static const std::string sep = "\r\n";

//\r\n用于区分长度len和其他报文

// 计算出报文的长度并其序列化
std::string Encode(std::string &jsonstr)
{
    int len = jsonstr.size();
    std::string lenstr = std::to_string(len);
    return lenstr + sep + jsonstr + sep; //"len"\r\n"{json}"\r\n 完整报文
}

// 取出有效载荷
// 报文有可能不完整，需要考虑所有情况：
//"le
//"len"
//"len"\r\n
//"len"\r\n"{js
//"len"\r\n"{json}"
//"len"\r\n"{json}"\r\n
//"len"\r\n"{json}"\r\n"len"
//"len"\r\n"{json}"\r\n"len"\r\n"{json}"\r\n
std::string Decode(std::string &packagestream)
{
    auto pos = packagestream.find(sep);
    if (pos == std::string::npos)
        return std::string();
    std::string lenstr = packagestream.substr(0, pos);
    int len = std::stoi(lenstr);
    int total = lenstr.size() + len + sep.size() * 2;
    if (packagestream.size() < total) // 如果实际报文大小与计算出来的大小不符，说明报文不完整
        return std::string();

    std::string jsonstr = packagestream.substr(pos + sep.size(), len);
    packagestream.erase(0, total);
    return jsonstr;
}

class Request
{
public:
    Request() {}
    Request(int x, int y, char oper) : _x(x), _y(y), _oper(oper) {}

    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["x"]=_x;
        root["y"]=_y;
        root["oper"]=_oper;

        Json::FastWriter writer;
        std::string s=writer.write(root);
        *out=s;
        return true;
    }

    bool Deserialize(std::string &in)
    {
        Json::Value root;
        Json::Reader reader;
        bool res=reader.parse(in,root);

        _x=root["x"].asInt();
        _y=root["y"].asInt();
        _oper=root["oper"].asInt();

        return true;
    }

    void Print()
    {
        std::cout<<_x<<std::endl;
        std::cout<<_y<<std::endl;
        std::cout<<_oper<<std::endl;
    }

    void SetValue(int x,int y,char oper)
    {
        _x=x;
        _y=y;
        _oper=oper;
    }

    char Oper()
    {
        return _oper;
    }

    int X()
    {
        return _x;
    }

    int Y()
    {
        return _y;
    }

private:
    int _x;
    int _y;
    char _oper;
};

class Response
{
    public:
    Response():_result(0),_code(0),_desc("success"){}

    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["result"]=_result;
        root["code"]=_code;
        root["desc"]=_desc;

        Json::FastWriter writer;
        std::string s=writer.write(root);
        *out=s;
        return true;
    }

    bool Deserialize(std::string &in)
    {
        Json::Value root;
        Json::Reader reader;
        bool res=reader.parse(in,root);
        if(!res)
        return false;

        _result=root["result"].asInt();
        _code=root["code"].asInt();
        _desc=root["desc"].asString();

        return true;
    }

    void PrintResult()
    {
        std::cout<<"result:"<<_result<<", code:"<<_code<<", desc:"<<_desc<<std::endl;
    }

public:
    int _result;
    int _code; //0:success, 1:div zero, 2:mod zero, 3:非法操作
    std::string _desc;
};

class Factory
{
public:
    static std::shared_ptr<Request> BuildRequestDefault()
    {
        return std::make_shared<Request>();
    }
    static std::shared_ptr<Response> BuildResponseDefault()
    {
        return std::make_shared<Response>();
    }
};